Skip to main content

10 定时器输入实验

定时器正交编码实验 定时器输入捕获实验

up的视频讲解: https://space.bilibili.com/1455872040

up视频里的正交编码实验代码: 👣OLED实验代码

up视频里的输入捕获实验代码: 👣OLED实验代码

1 🔃定时器正交编码实验​

1.1 实验连接​

图片

1.2 实验原理​

图片
  • 我们看到旋转编码器的原理图 右边是它的数据手册中给出的具体结构
  • 可以看到旋转编码器的A B两路默认上拉为高电平
  • 当我们旋动它的时候 旋转编码器里面的两个开关就交替导通 从而产生A B两路信号
图片

我们来简单分析一下它的状态序列

当顺时钟旋转的时候

  • 在旋转之前 A B 两个端子都为高电平1
  • 首先 A 端子先到低电平0
  • 其次 是 B 端子到0
  • 接着是 A 端子上拉到1
  • 最后 是 B 端子到1

同理 逆时针旋转

  • 首先是11
  • 然后是10
  • 00 01
  • 最后是11
图片

通过定时器内部的Encoder Interface正交编码模块 它具体有三种模式

  • TI12 也就是对AB两路信号都触发计数 一个完整的通断周期会产生 四个计数脉冲 也叫四分频模式
  • TI1 就只对一路信号触发计数 另一路只用来判定方向,一个完整的通断周期产生产生 两个计数脉冲
  • TI2 与TI1相同

1.3 CubeMX配置​

图片
图片

1.4 实验代码​

全局​

main()​

	HAL_TIM_Encoder_Start(&htim1,TIM_CHANNEL_ALL);

uint16_t counter = 0;

while(1)里面​

		counter =__HAL_TIM_GET_COUNTER(&htim1);
if(counter == 2)
{
//LED1
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,1);//黄灯亮
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,0);//红灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,1);//蓝灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,1);//绿灯灭
}
else if(counter ==4)
{
//LED2
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,0);//黄灯灭
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,1);//红灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,1);//蓝灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,1);//绿灯灭
}
else if(counter == 6)
{
//LED3
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,0);//黄灯灭
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,0);//红灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,0);//蓝灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,1);//绿灯灭
}
else if(counter == 8)
{
//LED4
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,0);//黄灯灭
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,0);//红灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,1);//蓝灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,0);//绿灯灭
}
else{
//LED关闭
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,0);//黄灯灭
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,0);//红灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,1);//蓝灯灭
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,1);//绿灯灭
}

2 🔃定时器输入捕获实验​

2.1 实验连接​

图片

2.2 实验原理​

图片

如果我们配置为下降沿触发的模式

  • 当A端子一个下降沿来的时候 边缘检测电路就会输出一个触发脉冲

  • 如果我们不进行分频 那么此时就会将CNT的值锁存到CCR

  • 并触发定时器输入捕获中断 我们就可以在中断里面读取CCR的值 从而得到当前的计数值

  • 当第二个下降沿来的时候就会触发第二个脉冲信号

  • 此时 CCR又会锁存当前 CNT的计数值

  • 然后触发中断 此时再到中断里面读取 CCR的值

我们将两个计数值 相减就可以得到两次边缘所间隔的CNT个数 然后再乘计数脉冲的周期就可以得到间隔的时间

图片

这个计数脉冲的周期具体是这样得到

  • 计数脉冲是 PSC预分频器对 RCC的时钟进行 PSC+1分频得到的
  • 所以说 计数脉冲的频率 就等于 RCC的时钟频率除以PSC加1
  • 同理 计数脉冲的周期 就是频率的倒数

通过这样的方法我们就可以的到两次边沿所间隔的时间

2.3 CubeMX配置​

图片
图片
图片

2.4 实验代码​

全局​

uint8_t flag = 0;
uint32_t cnt1 = 0;
uint32_t cnt2 = 0;

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM1)
{
if(flag == 0)
{
//cnt1
cnt1 = HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_1);
flag++;
}
else if(flag == 1)
{
//cnt2
cnt2 = HAL_TIM_ReadCapturedValue(&htim1,TIM_CHANNEL_1);
flag++;
}
}

}

main()​

	HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_1);
float time = 0;

while(1)里面​

		if(flag == 2)
{
//cnt2-cnt1 * T
if(cnt2-cnt1<0)
{
cnt2 += 65536;
}
time = (cnt2-cnt1)*0.0001;
printf("cnt1 = %d cnt2 = %d time = %f \r\n",cnt1,cnt2,time);
flag = 0;
}

✅捕获回绕与测量范围​

以上保留视频原代码。无符号计数差与回绕处理的工程化说明放在调试补充,不在视频代码中替换实现。

若计数时钟10 kHz,测量上限约6.5536秒。更慢信号要累计溢出次数或降低计数频率;缺少输入时还要设超时,不能一直沿用上一次的测量值。两次同极性边沿间隔为周期,异极性边沿间隔是脉宽。

正交编码器实验先慢转再快转,观察方向和每格计数。机械编码器存在抖动,滤波和解码倍频都会影响每格变化量;反向跳变不应一律解释为程序错误。